<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */
namespace app\service\cdc\append;

use app\enum\CommonEnum;
use app\enum\ServiceCostEnum;
use app\model\KsAdvertiserModel;
use app\model\mongo\MongoInfoModel;
use app\model\mongo\MongoKsVideoAppendSyncLogModel;
use app\model\mongo\MongoStatModel;
use app\model\mongo\MongoSyncModel;
use app\service\cdc\sync\KsVideoAppendSyncLogService;
use app\service\cdc\VideoService;
use app\service\client\AccountService;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;

class KsVideoAppendService extends VideoAppendService implements VideoInterface
{
    protected int $mediaId = CommonEnum::KS_MEDIA;

    protected ?MongoSyncModel $syncModel;

    protected ?MongoInfoModel $infoModel;

    protected ?MongoStatModel $statModel;

    /**
     * 获取中间表模型.
     */
    public static function getSyncModel(): MongoSyncModel
    {
        return new MongoKsVideoAppendSyncLogModel();
    }

    /**
     * 运行数据模型.
     * @param MongoSyncModel $model 中间件模型
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function runStat(MongoSyncModel $model): bool
    {
        $this->syncModel = $model;
        $lockKey = sprintf(ServiceCostEnum::CACHE_CONFIG['media_append_cost_lock'][CommonEnum::KS_MEDIA], strval($this->syncModel->getKey()));
        if (self::lock($lockKey, 1, 120)) {
            if (! $this->setModel()) {
                return false;
            }

            $info = AccountService::getAccountModel($model->getAttr('account_id'));
            $this->syncModel->setAttr('adv_id', $info['advertiser_id'] ?? '');
            return $this->appendStat();
        }
        return self::setError('加锁失败！lock_key:' . $lockKey);
    }

    /**
     * 新增日志.
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function addLogByInfo(MongoInfoModel $model): bool
    {
        $accountIds = self::getAccountIds($model->getAttr('user_id'));
        $statDate = intval(date('Ymd', $model->getAttr('upload_time')));

        foreach ($accountIds as $v) {
            $info = AccountService::getAccountModel($v['id']);

            VideoService::addSyncLog(static::getSyncModel(), [
                'client_id' => $model->getAttr('client_id'),
                'user_id' => $model->getAttr('user_id') ?? '',
                'account_id' => $v['id'],
                'adv_id' => trim($info['advertiser_id'] ?? ''),
                'signature' => $model->getAttr('signature'),
                'video_id' => $model->getAttr('photo_id'),
                'cost' => 0,
                'stat_date' => $statDate,
                'version' => $statDate,
                'type' => $model->getAttr('type'),
            ]);
        }

        return true;
    }

    /**
     * 获取账户Ids.
     * @param string $userId UserId
     */
    public static function getAccountIds(string $userId = ''): array
    {
        $sql = "SELECT
                    a.id,
                    v.advertiser_id
                FROM
                    habo_client_account AS a
                    LEFT JOIN habo_ks_advertiser AS v ON a.advertiser_id = v.advertiser_id 
                WHERE
                    v.user_id = '{$userId}'
                    AND v.auth_valid = " . KsAdvertiserModel::VALID_ENABLE;
        return Db::query($sql);
    }

    /**
     * 获取列表.
     * @return mixed
     */
    public static function getList(int $num = 0)
    {
        return KsVideoAppendSyncLogService::getList($num);
    }
}
